package com.xhcl.system.utils;



import java.math.BigDecimal;
import java.util.Stack;

public class MathUtil
{
  public static double round(double value, int scale, int roundingMode)
  {
    BigDecimal val = new BigDecimal(value);
    BigDecimal one = new BigDecimal("1");
    return val.divide(one, scale, roundingMode).doubleValue();
  }

  public static double round(double value, int scale)
  {
    int roundingMode = 4;
    BigDecimal val = new BigDecimal(value);
    BigDecimal one = new BigDecimal("1");
    return val.divide(one, scale, roundingMode).doubleValue();
  }

  public int priority(String op) {
    switch (op.charAt(0)) {
    case '+':
    case '-':
      return 1;
    case '*':
    case '/':
      return 2;
    case '(':
      return 0;
    case ')':
    case ',':
    case '.': } return 0;
  }

  public String calculate(BigDecimal o, BigDecimal e, String oper) {
    switch ("+-*/".indexOf(oper)) {
    case 0:
      return e.add(o).toString();
    case 1:
      return e.subtract(o).toString();
    case 2:
      return e.multiply(o).setScale(2, 4)
        .toString();
    case 3:
      return e.divide(o).setScale(2, 4).toString();
    }
    return "";
  }

  public BigDecimal calculate(String[] expression) {
    Stack oper = new Stack();
    Stack numb = new Stack();
    String opers = "+-*/()";
    for (int i = 0; i < expression.length; i++)
      if (opers.indexOf(expression[i]) == -1) {
        numb.push(expression[i]);
      }
      else if (oper.isEmpty()) {
        oper.push(expression[i]);
      }
      else
        switch (expression[i].charAt(0)) {
        case '(':
          oper.push(expression[i]);
          break;
        case '*':
        case '+':
        case '-':
        case '/':
          while ((!oper.empty()) && (priority((String)oper.peek()) > priority(expression[i]))) {
            numb.push(
              calculate(new BigDecimal((String)numb.pop()), 
              new BigDecimal((String)numb.pop()), (String)oper.pop()));
          }
          oper.push(expression[i]);
          break;
        case ')':
          while (!((String)oper.peek()).equals("(")) {
            numb.push(
              calculate(new BigDecimal((String)numb.pop()), 
              new BigDecimal((String)numb.pop()), (String)oper.pop()));
          }
          oper.pop();
        case ',':
        case '.':
        }
    while (!oper.empty()) {
      numb.push(
        calculate(new BigDecimal((String)numb.pop()), new BigDecimal(
        (String)numb.pop()), (String)oper.pop()));
    }
    return new BigDecimal((String)numb.pop());
  }
}